package com.youbug.kefu.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youbug.common.vo.QueryVo;
import com.youbug.kefu.entity.Message;
import com.youbug.kefu.mapper.MessageMapper;
import com.youbug.kefu.service.IMessageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 消息表 服务实现类
 * </p>
 *
 * @author youbug
 * @since 2023-01-07
 */
@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements IMessageService {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public IPage<Message> getMessagesByKeyword(QueryVo<Message> queryVo) {

        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        Message message = queryVo.getPayload();

        if(StringUtils.hasText(message.getContent())){

            String analyzer = StringUtils.hasText(message.getAnalyzer()) ? message.getAnalyzer() : "ik_smart";
            MatchQueryBuilder content = QueryBuilders.matchQuery("content", message.getContent()).analyzer(analyzer);

            boolQueryBuilder.must(content);
        }
        if(StringUtils.hasText(message.getSenderName())){

            MatchQueryBuilder senderName = QueryBuilders.matchQuery("sender_name", message.getSenderName());

            boolQueryBuilder.must(senderName);
        }

        if(!ObjectUtils.isEmpty((queryVo.getStartTime()))){

            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("create_time").from(queryVo.getStartTime()).timeZone("UTC+8").to(queryVo.getEndTime());

            boolQueryBuilder.must(rangeQueryBuilder);
        }

        searchQueryBuilder.withPageable(PageRequest.of(queryVo.getCurrentPage().intValue() - 1, queryVo.getPageSize().intValue()));

        FieldSortBuilder order = SortBuilders.fieldSort("create_time").order(SortOrder.DESC);

        searchQueryBuilder.withSort(order);

        searchQueryBuilder.withQuery(boolQueryBuilder);

        searchQueryBuilder.withHighlightBuilder(new HighlightBuilder().field("content"));

        searchQueryBuilder.withTrackScores(true);

        NativeSearchQuery query = searchQueryBuilder.build();

        SearchHits<Message> search = elasticsearchRestTemplate.search(query, Message.class);

        long totalHits = search.getTotalHits();

        List<Message> collect = search.getSearchHits().stream().map((hit)->{

            Message msg = hit.getContent();

            List<String> list = hit.getHighlightFields().get("content");

            if (!CollectionUtils.isEmpty(list)){
                msg.setContent(list.get(0));
            }
            return msg;
        }).collect(Collectors.toList());

        Page<Message> page = new Page<>();

        page.setCurrent(queryVo.getCurrentPage());
        page.setRecords(collect);
        page.setSize(queryVo.getPageSize());
        page.setTotal(totalHits);

        return page;
    }
}
